package de.slowpoke.flattr
{
	
	import de.slowpoke.flattr.Enum.*;
	import de.slowpoke.flattr.Error.FlattrError;
	import de.slowpoke.flattr.Utils.Convert;
	
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.sendToURL;

	
	/**
	 * The Thing class lets you submit new Things to the Flattr database.
	 */
	public class Thing
	{
		
		private var _flattr:Flattr;
		private var _url:String;
		private var _title:String;
		private var _description:String;
		private var _category:FlattrCategoryValue;
		private var _language:FlattrLanugageValue;
		private var _tags:String;
		private var _button:FlattrButtonValue;
		
		/**
		 * Instantiate a new Thing. Afterwards you can e.g. submit it to the Flattr database.
		 * 
		 * @param flattr		Flattr
		 * @param title			The title of your thing
		 * @param description	The description or excerpt for your thing.
		 * @param category		The category your thing should belong to. Use FlattrCategoryEnum for obtaining valid categories.
		 * @param language		The language of your thing. Use FlattrLanguageEnum for obtaining a valid language.
		 * @param tags			[Optional] A comma separated list of tags.
		 * @param url			[Optional] The url of your thing.
		 * @param button		[Optional] The button type. Use FlattrButtonEnum for obtaining valid button types. If no or an invalid value is set here, the default button will be used.
		 */
		public function Thing(flattr:Flattr, title:String, description:String, category:FlattrCategoryValue, language:FlattrLanugageValue, tags:String="", url:String="", button:FlattrButtonValue=null)
		{
			if(this._title == null)
				this.title = title;
			
			if(this._description == null)
				this.description = description;
			
			if(this._category == null)
				this.category = category;
			
			if(this._language == null)
				this.language = language;
			
			if(this._tags == null)
				this.tags = tags;
			
			if(this._url == null)
				this.url = url;
			
			if(this._button == null)
				this.button = button;
		}
		
		/**
		 * Submit your thing to the Flattr database.
		 * 
		 */
		public function submit():void
		{
			var data:String = Convert.bin2hex(	"uid=" + this._flattr.uid +
												"&url=" + this._url +
												"&title=" + this._title + 
												"&cat=" + this._category.toString() +
												"&tag=" + this._tags + 
												"&lng=" + this._language.toString() +
												"&button=" + this._button.toString() +
												"&desc=" + this._description);
			
			var req:URLRequest = new URLRequest(FlattrBase.API_BUTTON_VIEW + "/" + data);
			
			try {
				// TODO We are just sending here, since this might not run into any security issues.
				// For later we might want to handle responses somehow - this would require that Flattr provides a cross-domain policy file.
				sendToURL(req);
			} catch(error:Error){
				trace(error.message);
			}
			
		}
		
		/**
		 * Retrives the URL for flattr'ing a thing.<br>
		 * Note: This is not yet working.
		 * 
		 * @returns A String wich can be used for flattr'ing a thing.
		 */
		public function getFlattrUrl():String
		{
			// TODO The REST API is probalby needed for that ... or the thing-button-page needs to be parsed
			//		but still we would need to login first ... so we'll be waiting
			throw new FlattrError("Not yet implemented. Still waiting for the REST API");
			return "";
		}
		
		public function set url(url:String):void
		{
			if(url.length >= 0){
				this._url = url;
			} else {
				throw new FlattrError(FlattrError.EMPTY_URL);
			}
		}
		
		public function set title(title:String):void
		{
			if(title != "" || title.length > 0){
				this._title = title;
			} else {
				throw new FlattrError(FlattrError.EMPTY_TITLE);
			}
		}
		
		public function set description(desc:String):void
		{
			if(desc.length >= 0){
				this._description = desc;
			} else {
				throw new FlattrError(FlattrError.EMPTY_DESCRIPTION);
			}
		}
		
		public function set category(cat:FlattrCategoryValue):void
		{
			if(checkCat(cat)){
				this._category = cat;
			} else {
				throw new FlattrError(FlattrError.INVALID_CATEGORY);
			}
		}
		
		public function set language(lang:FlattrLanugageValue):void
		{
			if(checkLang(lang)){
				this._language = lang;
			} else {
				throw new FlattrError(FlattrError.INVALID_LANGUAGE);
			}
		}
		
		public function set tags(tags:String):void
		{
			this._tags = tags;
		}
		
		public function set button(btn:FlattrButtonValue):void
		{
			if(checkBtn(btn)){				
				this._button = btn;
			} else {
				this._button = FlattrButtonEnum.DEFAULT;
			}
		}
		
		/**
		 * Validates the supplied category string.
		 * 
		 * @param cat The Category
		 * @returns true if the category is valid, otherwise false.
		 */
		private function checkCat(cat:FlattrCategoryValue):Boolean
		{
			switch(cat.toString()){
				case FlattrCategoryEnum.TEXT.toString():
				case FlattrCategoryEnum.IMAGES.toString():
				case FlattrCategoryEnum.VIDEO.toString():
				case FlattrCategoryEnum.AUDIO.toString():
				case FlattrCategoryEnum.SOFTWARE.toString():
				case FlattrCategoryEnum.REST.toString():
					return true;
					
				default:
					return false;
			}
		}
		
		/**
		 * Validates the supplied button string.
		 * 
		 * @param cat The Button type
		 * @returns true if the button type is valid, otherwise false.
		 */
		private function checkBtn(btn:FlattrButtonValue):Boolean
		{
			switch(btn.toString()){
				case FlattrButtonEnum.DEFAULT.toString():
				case FlattrButtonEnum.COMPACT.toString():
					return true;
					
				default:
					return false;
			}
		}
		
		/**
		 * Validates the supplied language string.
		 * 
		 * @param cat The language
		 * @returns true if the language is valid, otherwise false.
		 */
		private function checkLang(lang:FlattrLanugageValue):Boolean
		{
			switch(lang.toString()){
				case FlattrLanguageEnum.ALBANIEN.toString():
				case FlattrLanguageEnum.ARABIC.toString():
				case FlattrLanguageEnum.BELARUS.toString():
				case FlattrLanguageEnum.BULGARIEN.toString():
				case FlattrLanguageEnum.CATALAN.toString():
				case FlattrLanguageEnum.CHINESE.toString():
				case FlattrLanguageEnum.CROATIAN.toString():
				case FlattrLanguageEnum.CZECH.toString():
				case FlattrLanguageEnum.DANISH.toString():
				case FlattrLanguageEnum.DUTCH.toString():
				case FlattrLanguageEnum.ENGLISH.toString():
				case FlattrLanguageEnum.ESTONIAN.toString():
				case FlattrLanguageEnum.FINNISH.toString():
				case FlattrLanguageEnum.FRENCH.toString():
				case FlattrLanguageEnum.GERMAN.toString():
				case FlattrLanguageEnum.GREEK.toString():
				case FlattrLanguageEnum.HEBREW.toString():
				case FlattrLanguageEnum.HINDI.toString():
				case FlattrLanguageEnum.HUNGARIAN.toString():
				case FlattrLanguageEnum.ICELANDIC.toString():
				case FlattrLanguageEnum.INDOSESIAN.toString():
				case FlattrLanguageEnum.IRISH.toString():
				case FlattrLanguageEnum.ITALIAN.toString():
				case FlattrLanguageEnum.JAPANESE.toString():
				case FlattrLanguageEnum.KOREAN.toString():
				case FlattrLanguageEnum.LATVIAN.toString():
				case FlattrLanguageEnum.LITHUANIAN.toString():
				case FlattrLanguageEnum.MACEDONIAN.toString():
				case FlattrLanguageEnum.MALAY.toString():
				case FlattrLanguageEnum.MALTESE.toString():
				case FlattrLanguageEnum.NORWEGIAN.toString():
				case FlattrLanguageEnum.POLISH.toString():
				case FlattrLanguageEnum.PORTUGUESE.toString():
				case FlattrLanguageEnum.ROMANIAN.toString():
				case FlattrLanguageEnum.RUSSIAN.toString():
				case FlattrLanguageEnum.SERBIAN.toString():
				case FlattrLanguageEnum.SLOVAK.toString():
				case FlattrLanguageEnum.SLOVENIAN.toString():
				case FlattrLanguageEnum.SPANISH.toString():
				case FlattrLanguageEnum.SWEDISH.toString():
				case FlattrLanguageEnum.THAI.toString():
				case FlattrLanguageEnum.TURKISH.toString():
				case FlattrLanguageEnum.UKRAINIAN.toString():
				case FlattrLanguageEnum.VIETNAMESE.toString():
					return true;
					
				default:
					return false;
			}
		}
		
	}
}